#include "headers/Model3d.h"
#include "headers/SpaceShip.h"
#include "headers/Utils.h"
#include "GL/gl.h"
#include "GL/glut.h"
#include <iostream>
#include <cmath>
#include "headers/HellGate.h"
#include "headers/Sweep.h"

#define NO_OF_TEXTURES 21
enum {BRIDGE_GROUND=0,BRIDGE_TRACK,BRIDGE_BASE_1,BRIDGE_BASE_2,BRIDGE_BASE_3,BRIDGE_BASE_4,
	BRIDGE_BASE_5, BRIDGE_UP_SIDE,BRIDGE_SIDE_SIDE,BRIDGE_SIDE_MID,BRIDGE_SIDE_HALF_CIRCLE1,
	BRIDGE_TOP_1,BRIDGE_TOP_2,BRIDGE_BRICK,BRIDGE_SIDE_OUT,BRIDGE_SIDE_OUT2,BRIDGE_SIDE_OUT_TOP,
	BRIDGE_BRICK_SD,BRIDGE_RELLING,BRIDGE_PILLAR_TOP,BRIDGE_PILLAR_MAIN
};
unsigned int texture[NO_OF_TEXTURES];	//the ids for the textures

using namespace std;

void HellGate::initTexture(){
	texture[BRIDGE_GROUND] = loadTexture("image/Asphalt_New.jpg",GL_UNSIGNED_BYTE);
	texture[BRIDGE_TRACK] = loadTexture("image/track.jpg",GL_UNSIGNED_BYTE);
	texture[BRIDGE_BASE_1] = loadTexture("image/base_1.jpg",GL_UNSIGNED_BYTE,GL_RGB);
	texture[BRIDGE_BASE_2] = loadTexture("image/base_2.jpg",GL_UNSIGNED_BYTE,GL_RGB);
	texture[BRIDGE_BASE_3] = loadTexture("image/base_3.jpg",GL_UNSIGNED_BYTE,GL_RGB);
	texture[BRIDGE_BASE_4] = loadTexture("image/base_4.jpg",GL_UNSIGNED_BYTE,GL_RGB);
	texture[BRIDGE_BASE_5] = loadTexture("image/base_5.jpg",GL_UNSIGNED_BYTE,GL_RGB);
	texture[BRIDGE_UP_SIDE] = loadTexture("image/up_side.png",GL_UNSIGNED_BYTE,GL_RGBA);
	texture[BRIDGE_SIDE_SIDE] = loadTexture("image/castle_side_side.jpg",GL_UNSIGNED_BYTE,GL_RGB);
	texture[BRIDGE_SIDE_MID] = loadTexture("image/castle_side_mid.jpg",GL_UNSIGNED_BYTE,GL_RGB);
	texture[BRIDGE_SIDE_HALF_CIRCLE1] = loadTexture("image/Material7.jpg",GL_UNSIGNED_BYTE,GL_RGB);
	texture[BRIDGE_TOP_1] = loadTexture("image/top_1.jpg",GL_UNSIGNED_BYTE,GL_RGB);
	texture[BRIDGE_TOP_2] = loadTexture("image/top_4.jpg",GL_UNSIGNED_BYTE,GL_RGB);
	texture[BRIDGE_BRICK] = loadTexture("image/brick_hd.jpg",GL_UNSIGNED_BYTE,GL_RGB);
	texture[BRIDGE_BRICK_SD] = loadTexture("image/brick.jpg",GL_UNSIGNED_BYTE,GL_RGB);
	texture[BRIDGE_SIDE_OUT] = loadTexture("image/side_1_part.jpg",GL_UNSIGNED_BYTE,GL_RGB);
	texture[BRIDGE_SIDE_OUT2] = loadTexture("image/side_1_part2.jpg",GL_UNSIGNED_BYTE,GL_RGB);
	texture[BRIDGE_SIDE_OUT_TOP] = loadTexture("image/side_1_top.jpg",GL_UNSIGNED_BYTE,GL_RGB);
	texture[BRIDGE_RELLING] = loadTexture("image/relling_trans.png",GL_UNSIGNED_BYTE,GL_RGBA);
	texture[BRIDGE_PILLAR_TOP] = loadTexture("image/pillar_top.jpg",GL_UNSIGNED_BYTE,GL_RGB);
	texture[BRIDGE_PILLAR_MAIN] = loadTexture("image/pillar_main.jpg",GL_UNSIGNED_BYTE,GL_RGB);
}

void HellGate::TopBeamFront(int seg_length, Vector3d square[],int len) {
	glPushMatrix();
	{
		glTranslatef(0, 50 - 18, 10);
		{
			for (int x = -160; x < 160; x += seg_length) {
				double y = cos(x / 160.0f * acos(-1)) * 18;
				double y1 = cos((x + seg_length) / 160.0f * acos(-1)) * 18;
				Sweep(Vector3d(x, y, 0), Vector3d(x + seg_length, y1, 0),
						square, len, 1, 0.1f).draw();
			}
		}
	}
	glPopMatrix();
}

void HellGate::TopBeamBack(int seg_length, Vector3d square[],int len) {
	glPushMatrix();
	{
		glTranslatef(0, 50 - 18, -10);
		{
			for (int x = -160; x < 160; x += seg_length) {
				double y = cos(x / 160.0f * acos(-1)) * 18;
				double y1 = cos((x + seg_length) / 160.0f * acos(-1)) * 18;
				Sweep(Vector3d(x, y, 0), Vector3d(x + seg_length, y1, 0),
						square, len, 1, 0.1f).draw();
			}
		}
	}
	glPopMatrix();
}

void HellGate::BottomBeamFront(int seg_length, Vector3d square[],int len) {
	glPushMatrix();
	{
		glTranslatef(0, 35 - 75, 10);
		{
			for (int x = -160; x <= 160; x += seg_length) {
				double y = cos(x / 320.0f * acos(-1)) * 75;
				double y1 = cos((x + seg_length) / 320.0f * acos(-1)) * 75;
				Sweep(Vector3d(x, y, 0), Vector3d(x + seg_length, y1, 0),
						square, len, 1, 0.1f).draw();
			}
		}
	}
	glPopMatrix();
}

void HellGate::BottomBeamBack(int seg_length, Vector3d square[],int len) {
	glPushMatrix();
	{
		glTranslatef(0, 35 - 75, -10);
		{
			for (int x = -160; x <= 160; x += seg_length) {
				double y = cos(x / 320.0f * acos(-1)) * 75;
				double y1 = cos((x + seg_length) / 320.0f * acos(-1)) * 75;
				Sweep(Vector3d(x, y, 0), Vector3d(x + seg_length, y1, 0),
						square, len, 1, 0.1f).draw();
			}
		}
	}
	glPopMatrix();
}

void HellGate::MainBeamJoinersFront(Vector3d square1[]) {
	float segments = 24.0f;
	glPushMatrix();
	{
		glTranslatef(0, 0, 10);
		{
			//verticle beam joiners
			Vector3d lasty;
			for (float x = -160 + 320 / segments / 2; x <= 160;
					x += 320 / segments) {
				double y = cos(x / 320.0f * acos(-1)) * 75 - 40;
				double y1 = cos(x / 160.0f * acos(-1)) * 18 + 32; //upper point
				Sweep(Vector3d(x, y1, 0), Vector3d(x, y, 0), square1, 4, 1, 0).draw();
				//Vector3d(x, y1, 0).showln();
				//Vector3d(x, y, 0).showln();
			}
			//cross beam joiners
			for (float x = -160 + 320 / segments / 2; x < 160;
					x += 320 / segments) {
				double y = cos(x / 320.0f * acos(-1)) * 75 - 40;
				double y1;
				if (x < 0) {
					y1 = cos((x + 320 / segments) / 160.0f * acos(-1)) * 18
							+ 32;
					Sweep(Vector3d(x, y, 0),
							Vector3d(x + 320 / segments, y1, 0), square1, 4, 1,
							0).draw();
				} else {
					y1 = cos((x - 320 / segments) / 160.0f * acos(-1)) * 18
							+ 32;
					Sweep(Vector3d(x, y, 0),
							Vector3d(x - 320 / segments, y1, 0), square1, 4, 1,
							0).draw();
				}
			}

		}
	}
	glPopMatrix();
}

void HellGate::MainBeamJoinersBack(Vector3d square1[]) {
	float segments = 24.0f;
	glPushMatrix();
	{
		glTranslatef(0, 0, -10);
		{
			//verticle beam joiners
			Vector3d lasty;
			for (float x = -160 + 320 / segments / 2; x <= 160;
					x += 320 / segments) {
				double y = cos(x / 320.0f * acos(-1)) * 75 - 40;
				double y1 = cos(x / 160.0f * acos(-1)) * 18 + 32; //upper point
				Sweep(Vector3d(x, y1, 0), Vector3d(x, y, 0), square1, 4, 1, 0).draw();
			}
			//cross beam joiners
			for (float x = -160 + 320 / segments / 2; x < 160;
					x += 320 / segments) {
				double y = cos(x / 320.0f * acos(-1)) * 75 - 40;
				double y1;
				if (x < 0) {
					y1 = cos((x + 320 / segments) / 160.0f * acos(-1)) * 18
							+ 32;
					Sweep(Vector3d(x, y, 0),
							Vector3d(x + 320 / segments, y1, 0), square1, 4, 1,
							0).draw();
				} else {
					y1 = cos((x - 320 / segments) / 160.0f * acos(-1)) * 18
							+ 32;
					Sweep(Vector3d(x, y, 0),
							Vector3d(x - 320 / segments, y1, 0), square1, 4, 1,
							0).draw();
				}
			}

		}
	}
	glPopMatrix();
}

void HellGate::MainBeamJoinerTop(Vector3d square3[]) {
	float segments = 24.0f;
	glPushMatrix();
	{
		glTranslatef(0, 50 - 18, 0);
		{
			float x;
			for (x = -160 + 320 / segments / 2; x <= 160 - 320 / segments;
					x += 320 / segments) {
				double y = cos(x / 160.0f * acos(-1)) * 18;
				double y1 = cos((x + 320 / segments) / 160.0f * acos(-1)) * 18;
				Vector3d v1f(x, y, 10), v2f(x + 320 / segments, y1, 10);
				Vector3d v1b(x, y, -10), v2b(x + 320 / segments, y1, -10);
				Sweep(v1f, v1b, square3, 4, 1, 0.1f).draw();
				Sweep(v1f, v2b, square3, 4, 1, 0.1f).draw();
				Sweep(v2f, v1b, square3, 4, 1, 0.1f).draw();
				//Sweep(v2f, v2b,square1, 4, 1, 0.1f).draw();
			}
			double y = cos(x / 160.0f * acos(-1)) * 18;
			double y1 = cos((x + 320 / segments) / 160.0f * acos(-1)) * 18;
			Vector3d v1f(x, y, 10), v2f(x + 320 / segments, y1, 10);
			Vector3d v1b(x, y, -10), v2b(x + 320 / segments, y1, -10);
			Sweep(v1f, v1b, square3, 4, 1, 0.1f).draw();
		}
	}
	glPopMatrix();
}

void HellGate::MainBeamJoinerBottom(Vector3d square4[]) {
	float segments = 24.0f;
	glPushMatrix();
	{
		glTranslatef(0, 35 - 75, 0);
		{
			float x;
			int seg_count = 0;
			for (x = -160 + 320 / segments / 2; x <= 160 - 320 / segments;
					x += 320 / segments) {

				double y = cos(x / 320.0f * acos(-1)) * 75;
				double y1 = cos((x + 320 / segments) / 320.0f * acos(-1)) * 75;
				Vector3d v1f(x, y, 10), v2f(x + 320 / segments, y1, 10);
				Vector3d v1b(x, y, -10), v2b(x + 320 / segments, y1, -10);
				if(seg_count != 4 && seg_count != 19)Sweep(v1f, v1b, square4, 4, 1, 0.1f).draw();
				if(seg_count != 3 && seg_count != 19)Sweep(v1f, v2b, square4, 4, 1, 0.1f).draw();
				if(seg_count != 3 && seg_count != 19)Sweep(v2f, v1b, square4, 4, 1, 0.1f).draw();

				seg_count++;

				//if(abs(x - (-160 + 320 / segments / 2 + 320 / segments*20)) > 1)Sweep(v1f, v1b, square4, 4, 1, 0.1f).draw();
				//if(abs(x - (-160 + 320 / segments / 2 + 320 / segments*21)) > 1)Sweep(v1f, v2b, square4, 4, 1, 0.1f).draw();
				//if(abs(x - (-160 + 320 / segments / 2 + 320 / segments*21)) > 1)Sweep(v2f, v1b, square4, 4, 1, 0.1f).draw();
			}
			double y = cos(x / 320.0f * acos(-1)) * 75;
			double y1 = cos((x + 320 / segments) / 320.0f * acos(-1)) * 75;
			Vector3d v1f(x, y, 10), v2f(x + 320 / segments, y1, 10);
			Vector3d v1b(x, y, -10), v2b(x + 320 / segments, y1, -10);
			Sweep(v1f, v1b, square4, 4, 1, 0.1f).draw();
		}
	}
	glPopMatrix();
}

void HellGate::SupportFront(Vector3d square1[]) {
	float segments = 24.0f;
	glPushMatrix();
	{
		glTranslatef(0, 0, 10);
		{
			//verticle beam joiners
			Vector3d lasty;
			for (float x = -160 + 320 / segments / 2; x <= 160;
					x += 320 / segments) {
				double y = cos(x / 320.0f * acos(-1)) * 75;
				if (y - 40 > 0)
					Sweep(Vector3d(x, -7, 0), Vector3d(x, y - 40, 0), square1, 4,
							1, 0).draw();
			}
		}
	}
	glPopMatrix();
}

void HellGate::SupportBack(Vector3d square1[]) {
	float segments = 24.0f;
	glPushMatrix();
	{
		glTranslatef(0, 0, -10);
		{
			//verticle beam joiners
			Vector3d lasty;
			for (float x = -160 + 320 / segments / 2; x <= 160;
					x += 320 / segments) {
				double y = cos(x / 320.0f * acos(-1)) * 75;
				if (y - 40 > 0)
					Sweep(Vector3d(x, -7, 0), Vector3d(x, y - 40, 0), square1, 4,
							1, 0).draw();
			}
		}
	}
	glPopMatrix();
}

void HellGate::RailRoadGround() {
	//Sweep(Vector3d(-160,-5,0),Vector3d(160,-5,0),square5,1,7.5).draw();
	float width = 15;
	float length = 1000;
	glColor4f(1,1,1,1);
	glPushAttrib(GL_ALL_ATTRIB_BITS);{
		//glDisable(GL_LIGHTING);
		glEnable(GL_LIGHTING);
		glEnable(GL_TEXTURE_2D);
		glDisable (GL_COLOR_MATERIAL);

		glBindTexture(GL_TEXTURE_2D, texture[BRIDGE_GROUND]);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
		glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
		glPushMatrix();
		{

			float width_rep = 1;
			float length_rep = 320 / 15.0 * width_rep;
			glTranslatef(0, -5, 0);
			glBegin (GL_QUADS);{
				glNormal3f (CO(J));
				glTexCoord2f(0, width_rep);
				glVertex3f(-length / 2, 0, width / 2);
				glTexCoord2f(0, 0);
				glVertex3f(-length / 2, 0, -width / 2);
				glTexCoord2f(length_rep, 0);
				glVertex3f(length / 2, 0, -width / 2);
				glTexCoord2f(length_rep, width_rep);
				glVertex3f(length / 2, 0, width / 2);
			}glEnd();
		}
		glPopMatrix();
		glBindTexture(GL_TEXTURE_2D, texture[BRIDGE_TRACK]);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
		glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
		float displace[] = {4.5,-.83,-4.3};
		for(int i = 0 ; i < 3 ; i++){
			glPushMatrix();
			{
				float width = 2.2;
				float width_rep = 1;
				float length_rep = length / width * width_rep;
				glTranslatef(0, -4.9, displace[i]);
				glBegin (GL_QUADS);{
					glNormal3f (CO(J));
					glTexCoord2f(0, width_rep);
					glVertex3f(-length / 2, 0, width / 2);
					glTexCoord2f(0, 0);
					glVertex3f(-length / 2, 0, -width / 2);
					glTexCoord2f(length_rep, 0);
					glVertex3f(length / 2, 0, -width / 2);
					glTexCoord2f(length_rep, width_rep);
					glVertex3f(length / 2, 0, width / 2);
				}glEnd();
			}
			glPopMatrix();
		}
	}glPopAttrib();
}

void HellGate::GroundSupport() {
	glEnable (GL_NORMALIZE);
	float segments = 24.0f;
	float length  =  1000;
	//draw gound support
	glPushMatrix();
	{
		glTranslatef(0, -7, 0);
		for (float x = -length/2 + length / segments / 2; x <= length/2;x += length / segments) {
			//Sweep(Vector3d(x,0,15),Vector3d(x,0,-15),square1,4,1).draw();
			glPushMatrix();
			{
				glTranslatef(x, 0, 0);
				glScalef(2, 2, 30);
				glutSolidCube(1);
			}
			glPopMatrix();
		}

	}
	glPopMatrix();
	glPushMatrix();
	{
		glTranslatef(0, -7, -10);
		glScalef(length, 2, 2);
		glutSolidCube(1);
	}
	glPopMatrix();
	glPushMatrix();
	{
		glTranslatef(0, -7, 10);
		glScalef(length, 2, 2);
		glutSolidCube(1);
	}
	glPopMatrix();
	glPushMatrix();
	{
		glTranslatef(0, -7, -15);
		glScalef(length, 2, 2);
		glutSolidCube(1);
	}
	glPopMatrix();
	glPushMatrix();
	{
		glTranslatef(0, -7, 15);
		glScalef(length, 2, 2);
		glutSolidCube(1);
	}
	glPopMatrix();
	glDisable(GL_NORMALIZE);
}

void HellGate::SideNets() {
	//side nets
	float width = 15.2;
	int from = 160;
	int to = 160;
	glPushMatrix();
	{
		glTranslatef(0, -6, -width);
		for (float x = -from; x < to; x += 0.3) {
			glLineWidth(2);
			glBegin (GL_LINES);
			{
				glVertex2f(x, 0);
				glVertex2f(x + 4, 4);
				glVertex2f(x, 0);
				glVertex2f(x - 4, 4);
			}
			glEnd();
		}
	}
	glPopMatrix();
	glPushMatrix();
	{
		glTranslatef(0, -6, width);
		for (float x = -from; x < to; x += 0.3) {
			glLineWidth(2);
			glBegin (GL_LINES);
			{
				glVertex2f(x, 0);
				glVertex2f(x + 4, 4);
				glVertex2f(x, 0);
				glVertex2f(x - 4, 4);
			}
			glEnd();
		}
	}
	glPopMatrix();
	glEnable (GL_NORMALIZE);
	glPushMatrix();
	{
		glTranslatef(0, -2, -width);
		glScalef(320, 0.1, 0.1);
		glutSolidCube(1);
	}
	glPopMatrix();
	glPushMatrix();
	{
		glTranslatef(0, -2, width);
		glScalef(320, 0.1, 0.1);
		glutSolidCube(1);
	}
	glPopMatrix();
	glPushMatrix();
	{
		glTranslatef(0, -6, 0);
		for (float x = -from; x < to; x += 4.5) {
			glLineWidth(4);
			glBegin (GL_LINES);{
				glVertex3f(x, 0, width);
				glVertex3f(x, 4, width);
				glVertex3f(x, 0, -width);
				glVertex3f(x, 4, -width);
			}glEnd();
		}
	}
	glPopMatrix();
	glDisable(GL_NORMALIZE);
	glLineWidth(1);
}

void HellGate::DrawMainBridge() {
	glColor3f(0.5f, 0.2f, 0.2f);
	int seg_length = 10;
	Vector3d square1[] = { Vector3d(-1, 1, 0), Vector3d(1, 1, 0), Vector3d(1,
			-1, 0), Vector3d(-1, -1, 0), Vector3d(-1, 1, 0) };
	TopBeamFront(seg_length, square1, 4);
	TopBeamBack(seg_length, square1, 4);
	Vector3d square2[] = { Vector3d(-1, 2, 0), Vector3d(1, 2, 0), Vector3d(1,
			-2, 0), Vector3d(-1, -2, 0), Vector3d(-1, 2, 0) };
	BottomBeamFront(seg_length, square2, 4);
	BottomBeamBack(seg_length, square2, 4);
	MainBeamJoinersFront(square1);
	MainBeamJoinersBack(square1);
	float x = 0.15f;
	Vector3d square3[] = { Vector3d(-1, 1 - x, 0), Vector3d(1, 1 - x, 0),
			Vector3d(1, -1 + x, 0), Vector3d(-1, -1 + x, 0), Vector3d(-1, 1 - x,
					0) };
	MainBeamJoinerTop(square3);
	x = 0.35f;
	float y = .25f;
	Vector3d square4[] = { Vector3d(-1 + x, 1 - y, 0), Vector3d(1 - x, 1 - y,
			0), Vector3d(1 - x, -1 + y, 0), Vector3d(-1 + x, -1 + y, 0),
			Vector3d(-1 + x, 1 - y, 0) };
	MainBeamJoinerBottom(square4);
	SupportFront(square4);
	SupportBack(square4);
	GroundSupport();
	//side nets
	SideNets();
	//draw rail ground
	RailRoadGround();
}

void HellGate::TexturedQuad(float width,float height,float upper_extend,float lower_extend,bool rep,float force_rep) {
	//glTranslatef(0, -5, 0);
	glPushAttrib(GL_ALL_ATTRIB_BITS);
	float p = force_rep;
	float q = force_rep;
	if(rep){
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
		if(width<height)  q = height/width;
		else p = width/height;
	}
	glBegin (GL_QUADS);
	{
		glNormal3f (CO(K));
		glTexCoord2f(0, 0);
		glVertex3f(width / 2+upper_extend, height / 2, upper_extend);
		glTexCoord2f(p, 0);
		glVertex3f(-(width / 2+upper_extend), height / 2 , upper_extend);
		glTexCoord2f(p, q);
		glVertex3f(-(width / 2+lower_extend), -(height / 2), lower_extend);
		glTexCoord2f(0, q);
		glVertex3f(width / 2+lower_extend, -(height / 2), lower_extend);
	}
	glEnd();

	glPopAttrib();

}


void HellGate::TexturedQuad2(float width,float height,float upper_extend,float lower_extend,bool rep,float force_rep) {
	//glTranslatef(0, -5, 0);
	glPushAttrib(GL_ALL_ATTRIB_BITS);
	float p = force_rep;
	float q = force_rep;
	if(rep){
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
		if(width<height)  q = height/width;
		else p = width/height;
	}
	glBegin (GL_QUADS);
	{
		glNormal3f (CO(K));
		glTexCoord2f(0, 0);
		glVertex3f(width / 2+upper_extend, height / 2, upper_extend);
		glTexCoord2f(p, 0);
		glVertex3f(-(width / 2+upper_extend), height / 2 , upper_extend);
		glTexCoord2f(p, q);
		glVertex3f(-(width / 2), -(height / 2), lower_extend);
		glTexCoord2f(0, q);
		glVertex3f(width / 2, -(height / 2), lower_extend);
	}
	glEnd();

	glPopAttrib();

}
void HellGate::BaseSweep(float height, float upper_extend, float lower_extend,bool repeatTexture) {
	float width = 17.56;
	glPushMatrix();
	{
		glTranslatef(0, 0, 18);
		TexturedQuad(width, height, upper_extend, lower_extend,repeatTexture);
	}
	glPopMatrix();
	glPushMatrix();
	{
		glRotatef(180, 0, 1, 0);
		glTranslatef(0, 0, 18);
		TexturedQuad(width, height, upper_extend, lower_extend,repeatTexture);
	}
	glPopMatrix();
	width = 36;
	glPushMatrix();
	{
		glRotatef(-90, 0, 1, 0);
		glTranslatef(0, 0, 17.56 / 2);
		TexturedQuad(width, height, upper_extend, lower_extend,repeatTexture);
	}
	glPopMatrix();
	glPushMatrix();
	{
		glRotatef(90, 0, 1, 0);
		glTranslatef(0, 0, 17.56 / 2);
		TexturedQuad(width, height, upper_extend, lower_extend,repeatTexture);
	}
	glPopMatrix();
}

void HellGate::TopSweep(float height, float upper_extend, float lower_extend,float width1,float width2,bool repeatTexture) {
	float width = width1;
	glPushMatrix();
	{
		glTranslatef(0, 0, width2/2);
		TexturedQuad(width, height, upper_extend, lower_extend,repeatTexture);
	}
	glPopMatrix();
	glPushMatrix();
	{
		glRotatef(180, 0, 1, 0);
		glTranslatef(0, 0, width2/2);
		TexturedQuad(width, height, upper_extend, lower_extend,repeatTexture);
	}
	glPopMatrix();
	width = width2;
	glPushMatrix();
	{
		glRotatef(-90, 0, 1, 0);
		glTranslatef(0, 0, width1 / 2);
		TexturedQuad(width, height, upper_extend, lower_extend,repeatTexture);
	}
	glPopMatrix();
	glPushMatrix();
	{
		glRotatef(90, 0, 1, 0);
		glTranslatef(0, 0, width1 / 2);
		TexturedQuad(width, height, upper_extend, lower_extend,repeatTexture);
	}
	glPopMatrix();
}



void HellGate::CastleBase() {
	//glDisable(GL_LIGHTING);
	//glColor4f(1, 1, 1, 1);
	glDisable (GL_COLOR_MATERIAL);
	glPushMatrix();
	{
		glBindTexture(GL_TEXTURE_2D, texture[BRIDGE_BASE_1]);
		glTranslatef(0, -11.32 / 2, 0);
		BaseSweep(11.32, 0, 0);
		glTranslatef(0, -11.32 / 2, 0);
		glBindTexture(GL_TEXTURE_2D, texture[BRIDGE_BASE_2]);
		glTranslatef(0, -13.12 / 2, 0);
		BaseSweep(13.12, 0, 2);
		glTranslatef(0, -13.12 / 2, 0);
		glBindTexture(GL_TEXTURE_2D, texture[BRIDGE_BASE_3]);
		glTranslatef(0, -2.43 / 2, 0);
		BaseSweep(2.43, 2, 4);
		glTranslatef(0, -2.43 / 2, 0);
		glBindTexture(GL_TEXTURE_2D, texture[BRIDGE_BASE_4]);
		glTranslatef(0, -2 / 2, 0);
		BaseSweep(2, 4, 2);
		glTranslatef(0, -2 / 2, 0);
		glBindTexture(GL_TEXTURE_2D, texture[BRIDGE_BASE_5]);
		glTranslatef(0, -10.3 / 2, 0);
		BaseSweep(10.3, 2, 4);
	}
	glPopMatrix();
}

void HellGate::CastleSideSide(float scale,float offset) {
	//castle up
	glPushMatrix();
	{
		float width = 5.28f;
		float height = 18.81f;
		glScalef(scale, 1, 1);
		glTranslatef(-17.56 / 2 + width / 2, height / 2, offset);

		glBegin (GL_QUADS);
		{
			glNormal3f (CO(K));glTexCoord2f(0, 0);
			glVertex3f(width / 2, height / 2, 0);
			glTexCoord2f(1, 0);
			glVertex3f(-(width / 2), height / 2, 0);
			glTexCoord2f(1, 1);
			glVertex3f(-(width / 2), -(height / 2), 0);
			glTexCoord2f(0, 1);
			glVertex3f(width / 2, -(height / 2), 0);
		}
		glEnd();
	}
	glPopMatrix();
}

void HellGate::TopSideOutOut(float scale,float offset) {
	glBindTexture(GL_TEXTURE_2D, texture[BRIDGE_SIDE_OUT2]);
	glPushMatrix();
	{
		float width = 2.98f;
		float height = 18.81f;
		glScalef(scale, 1, 1);
		glTranslatef(-offset / 2, height / 2, 18 - width / 2);
		glRotatef(-90, 0, 1, 0);
		TexturedQuad(width, height, 0, 0);
	}
	glPopMatrix();
	glBindTexture(GL_TEXTURE_2D, texture[BRIDGE_SIDE_OUT]);
	glPushMatrix();
	{
		float width = 2.26f;
		float height = 18.81f;
		glScalef(scale, 1, 1);
		glTranslatef(-offset / 2, height / 2, 18 - (width / 2 + 2.89 + 4.32));
		glRotatef(-90, 0, 1, 0);
		TexturedQuad(width, height, 0, 0);
	}
	glPopMatrix();





}

void HellGate::sideDiskAndCylinderOut(double scale) {

	//disk
	glPushMatrix();
	{
		double d = 4.32;
		glScalef(scale, 1, 1);
		glTranslatef(17.56 / 2, 7.73, 18 - 2.89 - d / 2);
		glRotatef(90, 0, 1, 0);
		GLUquadricObj* qObj = gluNewQuadric();
		gluQuadricNormals(qObj, GLU_SMOOTH);
		gluQuadricTexture(qObj, GL_TRUE);
		glBindTexture(GL_TEXTURE_2D, texture[BRIDGE_BRICK]);
		gluQuadricOrientation(qObj, GLU_OUTSIDE);
		GLdouble eqn1[] = { 0.0, 1.0, 0.0, 0.0 };
		glClipPlane(GL_CLIP_PLANE0, eqn1);
		glEnable (GL_CLIP_PLANE0);
		gluDisk(qObj, d / 2, d / 2 + 2, 20, 20);
		glDisable(GL_CLIP_PLANE0);
	}
	glPopMatrix();
	glPushMatrix();
	{
		double d = 4.32;
		glScalef(scale, 1, 1);
		glTranslatef(17.56 / 2 - 5.28, 7.73, 18 - 2.89 - d / 2);
		glRotatef(90, 0, 1, 0);
		GLUquadricObj* qObj = gluNewQuadric();
		gluQuadricNormals(qObj, GLU_SMOOTH);
		gluQuadricTexture(qObj, GL_TRUE);
		glBindTexture(GL_TEXTURE_2D, texture[BRIDGE_BRICK]);
		gluQuadricOrientation(qObj, GLU_OUTSIDE);
		GLdouble eqn1[] = { 0.0, 1.0, 0.0, 0.0 };
		glClipPlane(GL_CLIP_PLANE0, eqn1);
		glEnable (GL_CLIP_PLANE0);
		gluDisk(qObj, d / 2, d / 2 + 2, 20, 20);
		glDisable(GL_CLIP_PLANE0);
	}
	glPopMatrix();




	//top cover
	glBindTexture(GL_TEXTURE_2D, texture[BRIDGE_BRICK_SD]);
	glPushMatrix();
	{
		float width = 4.32f;
		float height = 8.36f;
		glScalef(scale, 1, 1);
		glTranslatef(17.56/2, 15, 18 - (width / 2 + 2.89 ));
		glRotatef(90, 0, 1, 0);
		TexturedQuad(width, height, 0, 0);
	}
	glPopMatrix();

	//top cover inner
	glBindTexture(GL_TEXTURE_2D, texture[BRIDGE_BRICK_SD]);
	glPushMatrix();
	{
		float width = 4.32f;
		float height = 8.36f;
		glScalef(scale, 1, 1);
		glTranslatef(17.56/2 - 5.28, 15, 18 - (width / 2 + 2.89 ));
		glRotatef(90, 0, 1, 0);
		TexturedQuad(width, height, 0, 0);
	}
	glPopMatrix();




	//bottom cover
	glBindTexture(GL_TEXTURE_2D, texture[BRIDGE_BRICK_SD]);
	glPushMatrix();
	{
		float width = 4.32f;
		float height = 2.44f;
		glScalef(scale, 1, 1);
		glTranslatef(17.56/2, height/2, 18 - (width / 2 + 2.89 ));
		glRotatef(90, 0, 1, 0);
		TexturedQuad(width, height, 0, 0);
	}
	glPopMatrix();




	glPushMatrix();
	{
		float rad = 4.32f;
		float len = 5.28f;

		glScalef(scale,1,1);
		glTranslatef(-17.56/2, 7.75, 18 -5);
		glRotatef(90,0,1,0);
		//glRotatef(-90,1,0,0);
		GLUquadricObj* qObj = gluNewQuadric();
		gluQuadricNormals(qObj, GLU_SMOOTH);
		gluQuadricTexture(qObj, GL_TRUE);
		glBindTexture(GL_TEXTURE_2D, texture[BRIDGE_BRICK]);
		glRotatef(180, 0, 0, 1);
		gluQuadricOrientation(qObj, GLU_INSIDE);
		GLdouble eqn0[] = { 0.0, -1.0, 0.0, 0.0 };
		glClipPlane(GL_CLIP_PLANE0, eqn0);
		glEnable (GL_CLIP_PLANE0);
		gluCylinder(qObj, rad / 2, rad / 2, len, 20, 20);
		glDisable(GL_CLIP_PLANE0);

	}
	glPopMatrix();
}

void HellGate::CastleFront() {
	//castle up
	glBindTexture(GL_TEXTURE_2D, texture[BRIDGE_SIDE_SIDE]);
	CastleSideSide(1, 18);
	CastleSideSide(-1, 18);
	CastleSideSide(1, 18 - 2.89);
	CastleSideSide(-1, 18 - 2.89);
	CastleSideSide(1, 18 - 7.21);
	CastleSideSide(-1, 18 - 7.21);
	CastleSideSide(1, 18 - 9.47);
	CastleSideSide(-1, 18 - 9.47);
	glBindTexture(GL_TEXTURE_2D, texture[BRIDGE_SIDE_MID]);
	glPushMatrix();
	{
		float width = 7.0f;
		float height = 2.44f;
		glTranslatef(0, height / 2, 18);
		TexturedQuad(width, height, 0, 0);
	}
	glPopMatrix();
	//draw the half circled texture at side
	glPushMatrix();
	{
		glTranslatef(0, 12, 18);
		GLUquadricObj* qObj = gluNewQuadric();
		gluQuadricNormals(qObj, GLU_SMOOTH);
		gluQuadricTexture(qObj, GL_TRUE);
		glBindTexture(GL_TEXTURE_2D, texture[BRIDGE_BRICK]);
		gluQuadricOrientation(qObj, GLU_OUTSIDE);
		GLdouble eqn1[] = { 0.0, 1.0, 0.0, 0.0 };
		glClipPlane(GL_CLIP_PLANE0, eqn1);
		glEnable (GL_CLIP_PLANE0);
		gluDisk(qObj, 7 / 2.0, 16.0 / 2, 20, 20);
		glDisable(GL_CLIP_PLANE0);
	}
	glPopMatrix();
	//side out*************************************************************
	TopSideOutOut(1, 17.56);
	TopSideOutOut(-1, 17.56);
	TopSideOutOut(1, 7);
	TopSideOutOut(-1, 7);
	//side side circle
	sideDiskAndCylinderOut(1);
	sideDiskAndCylinderOut(-1);
	//top part
	glPushMatrix();
	{
		glBindTexture(GL_TEXTURE_2D, texture[BRIDGE_TOP_1]);
		glTranslatef(0, 23.3 - 4.5 / 2, 18-9.47/2);
		TopSweep(4.5, 1, 0,17.56,9.47, true);
	}
	glPopMatrix();
	glPushMatrix();
	{
		glBindTexture(GL_TEXTURE_2D, texture[BRIDGE_TOP_1]);
		glTranslatef(0, 23.3 + 2.2 / 2, 18-9.47/2);
		TopSweep(2.2, 1, 1,17.56,9.47, true);
	}
	glPopMatrix();

	glPushMatrix();
	{
		glBindTexture(GL_TEXTURE_2D, texture[BRIDGE_TOP_1]);
		glTranslatef(0, 23.3 - 3.8 / 2, 0);
		TopSweep(3.8, 1, 0,11.63,18.66, true);
	}
	glPopMatrix();
	glPushMatrix();
	{
		glBindTexture(GL_TEXTURE_2D, texture[BRIDGE_TOP_1]);
		glTranslatef(0, 23.3 + 2.2 / 2, 0);
		TopSweep(2.2, 1, 1,11.62,18.66, true);
	}
	glPopMatrix();


	//ceiling
	glBindTexture(GL_TEXTURE_2D, texture[BRIDGE_BRICK]);
	glPushMatrix();
	{
		float width = 16.54f;
		float height = 8.15f;
		glTranslatef(0, 23.3 + 2.2 + 1.21, 18 - 1.6 - height / 2 + 1);
		glRotatef(-90, 1, 0, 0);
		TexturedQuad(width, height, 0, 0, true, 1);
	}
	glPopMatrix();
	glPushMatrix();
	{
		float width = 20.0f;
		float height = 11.47;
		glTranslatef(0, 23.3 + 2.2, 18 - height / 2 + 1);
		glRotatef(-90, 1, 0, 0);
		TexturedQuad(width, height, 0, 0, true, 1);
	}
	glPopMatrix();
	//inner circular
	glPushMatrix();
	{
		float rad = 7.0f;
		float len = 10.47 + 0.9;
		glTranslatef(0, 12, 18 - len);
		//glRotatef(-90,1,0,0);
		GLUquadricObj* qObj = gluNewQuadric();
		gluQuadricNormals(qObj, GLU_SMOOTH);
		gluQuadricTexture(qObj, GL_TRUE);
		glBindTexture(GL_TEXTURE_2D, texture[BRIDGE_BRICK]);
		glRotatef(180, 0, 0, 1);
		gluQuadricOrientation(qObj, GLU_INSIDE);
		GLdouble eqn0[] = { 0.0, -1.0, 0.0, 0.0 };
		glClipPlane(GL_CLIP_PLANE0, eqn0);
		GLdouble eqn1[] = { 0.0, -0.9, 3.5, -3.5 * 0.9 };
		glClipPlane(GL_CLIP_PLANE1, eqn1);
		glEnable (GL_CLIP_PLANE0);
		glEnable (GL_CLIP_PLANE1);
		gluCylinder(qObj, rad / 2, rad / 2, len, 20, 20);
		glDisable(GL_CLIP_PLANE0);
		glDisable(GL_CLIP_PLANE1);
	}
	glPopMatrix();
	//right partial
	glPushMatrix();
	{
		float rad = 15.0f;
		float len = 2.5;
		glRotatef(90, 0, 1, 0);
		glTranslatef(0, 12, -6);
		//glRotatef(-90,1,0,0);
		GLUquadricObj* qObj = gluNewQuadric();
		gluQuadricNormals(qObj, GLU_SMOOTH);
		gluQuadricTexture(qObj, GL_TRUE);
		glBindTexture(GL_TEXTURE_2D, texture[BRIDGE_BRICK]);
		gluQuadricOrientation(qObj, GLU_INSIDE);
		GLdouble eqn1[] = { 0.0, -1.0, 0.0, 0.0 };
		glRotatef(180, 0, 0, 1);
		glClipPlane(GL_CLIP_PLANE0, eqn1);
		glEnable (GL_CLIP_PLANE0);
		gluCylinder(qObj, rad / 2, rad / 2, len, 20, 20);
		glDisable(GL_CLIP_PLANE0);
	}
	glPopMatrix();
	//left partial
	glPushMatrix();
	{
		float rad = 15.0f;
		float len = 2.5;
		glRotatef(90, 0, 1, 0);
		glTranslatef(0, 12, 6 - len);
		//glRotatef(-90,1,0,0);
		GLUquadricObj* qObj = gluNewQuadric();
		gluQuadricNormals(qObj, GLU_SMOOTH);
		gluQuadricTexture(qObj, GL_TRUE);
		glBindTexture(GL_TEXTURE_2D, texture[BRIDGE_BRICK]);
		gluQuadricOrientation(qObj, GLU_INSIDE);
		GLdouble eqn1[] = { 0.0, -1.0, 0.0, 0.0 };
		glRotatef(180, 0, 0, 1);
		glClipPlane(GL_CLIP_PLANE0, eqn1);
		glEnable (GL_CLIP_PLANE0);
		gluCylinder(qObj, rad / 2, rad / 2, len, 20, 20);
		glDisable(GL_CLIP_PLANE0);
	}
	glPopMatrix();


	//floor
	glPushMatrix();
	{
		float width = 17.56f;
		float height = 9.47f;
		glRotatef(-90, 1, 0, 0);
		glTranslatef(0, 18-height/2, 2.44);

		TexturedQuad(width, height, 0, 0, true, 1);
	}glPopMatrix();




	//part of center
	glBindTexture(GL_TEXTURE_2D, texture[BRIDGE_BRICK_SD]);
	CastleCenterSideSweep(1);
	CastleCenterSideSweep(-1);


}

void HellGate::CastleCenterSideSweep(float scale) {
	glPushMatrix();
	{
		float width = 1.0f;
		float height = 12.0f;
		glScalef(scale, 1, 1);
		glTranslatef(-6, height / 2, 8);
		glRotatef(-90, 0, 1, 0);
		TexturedQuad(width, height, 0, 0);
	}
	glPopMatrix();
	glPushMatrix();
	{
		float width = 1.0f;
		float height = 12.0f;
		glScalef(scale, 1, 1);
		glTranslatef(-6 + 2.54, height / 2, 8);
		glRotatef(-90, 0, 1, 0);
		TexturedQuad(width, height, 0, 0);
	}
	glPopMatrix();
	glPushMatrix();
	{
		float width = 2.54f;
		float height = 18.81f;
		glScalef(scale, 1, 1);
		glTranslatef(-17.56 / 2 + width / 2 + 2.7, height / 2, 7.5);
		glBegin (GL_QUADS);
		{
			glNormal3f (CO(K));glTexCoord2f(0, 0);
			glVertex3f(width / 2, height / 2, 0);
			glTexCoord2f(1, 0);
			glVertex3f(-(width / 2), height / 2, 0);
			glTexCoord2f(1, 1);
			glVertex3f(-(width / 2), -(height / 2), 0);
			glTexCoord2f(0, 1);
			glVertex3f(width / 2, -(height / 2), 0);
		}
		glEnd();
	}
	glPopMatrix();
}

void HellGate::CastleCenterDisk(float scale) {
	glPushMatrix();
	{
		glScalef(scale, 1, 1);
		glRotatef(90, 0, 1, 0);
		glTranslatef(0, 12, 6);
		GLUquadricObj* qObj = gluNewQuadric();
		gluQuadricNormals(qObj, GLU_SMOOTH);
		gluQuadricTexture(qObj, GL_TRUE);
		glBindTexture(GL_TEXTURE_2D, texture[BRIDGE_BRICK]);
		gluQuadricOrientation(qObj, GLU_OUTSIDE);
		GLdouble eqn1[] = { 0.0, 1.0, 0.0, 0.0 };
		glClipPlane(GL_CLIP_PLANE0, eqn1);
		glEnable (GL_CLIP_PLANE0);
		gluDisk(qObj, 15 / 2.0, 13, 20, 20);
		glDisable(GL_CLIP_PLANE0);
	}
	glPopMatrix();
}

void HellGate::CastleTopRelling(float offSet) {
	glBindTexture(GL_TEXTURE_2D, texture[BRIDGE_RELLING]);
	glPushMatrix();
	{
		float height = 4.0f;
		float width = 16.54f;
		glTranslatef(0, 25.25 + height / 2, offSet);
		//glRotatef(-90, 1, 0, 0);
		TexturedQuad(width, height, 0, 0, true, 1);
	}
	glPopMatrix();
	glBindTexture(GL_TEXTURE_2D, texture[BRIDGE_RELLING]);
	glPushMatrix();
	{
		float height = 4.0f;
		float width = 8.15f;
		glTranslatef(8.27, 25.25 + height / 2, offSet - width / 2);
		glRotatef(90, 0, 1, 0);
		//glRotatef(-90, 1, 0, 0);
		TexturedQuad(width, height, 0, 0, true, 1);
	}
	glPopMatrix();
	glBindTexture(GL_TEXTURE_2D, texture[BRIDGE_RELLING]);
	glPushMatrix();
	{
		float height = 4.0f;
		float width = 8.15f;
		glTranslatef(-8.27, 25.25 + height / 2, offSet - width / 2);
		glRotatef(90, 0, 1, 0);
		//glRotatef(-90, 1, 0, 0);
		TexturedQuad(width, height, 0, 0, true, 1);
	}
	glPopMatrix();
	glBindTexture(GL_TEXTURE_2D, texture[BRIDGE_RELLING]);
	glPushMatrix();
	{
		float height = 4.0f;
		float width = 4.0f;
		glTranslatef(-(4.44 + width / 2), 25.25 + height / 2, offSet - 8.15);
		//glRotatef(-90,0,1,0);
		//glRotatef(-90, 1, 0, 0);
		TexturedQuad(width, height, 0, 0, true, 1);
	}
	glPopMatrix();
	glBindTexture(GL_TEXTURE_2D, texture[BRIDGE_RELLING]);
	glPushMatrix();
	{
		float height = 4.0f;
		float width = 4.0f;
		glTranslatef((4.44 + width / 2), 25.25 + height / 2, offSet - 8.15);
		//glRotatef(-90,0,1,0);
		//glRotatef(-90, 1, 0, 0);
		TexturedQuad(width, height, 0, 0, true, 1);
	}
	glPopMatrix();
}

void HellGate::DrawCastle() {
	//DrawMainBridge();
	//draw side castle
	glPushAttrib (GL_ALL_ATTRIB_BITS);
	{
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
		glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
		CastleBase();
		//castle up
		CastleFront();
		glPushMatrix();
		{
			glRotatef(180, 0, 1, 0);
			CastleFront();
		}
		glPopMatrix();
		// the big one
		glPushMatrix();
		{
			glRotatef(90, 0, 1, 0);
			glTranslatef(0, 12, -3.5);
			float r = 3.5f;
			float offset = 7;
			for (float alpha = 0; alpha < 180; alpha += 22.5) {
				glPushMatrix();
				{
					double a = alpha * PI / 180;
					double b = (alpha + 22.5) * PI / 180;
					float x0 = r + r * cos(a);
					float y0 = r * sin(a);
					float x1 = r + r * cos(b);
					float y1 = r * sin(b);

					double c = y1 * (x0 - x1) + x1 * (y1 - y0);

					double coOff_y = (x0 - x1) / c;
					double coOff_z = (y1 - y0) / c;

					float radofcylinder = 15.0f;
					float len = x0 - x1;
					offset -= len;
					//cout << len << endl;
					//glRotatef(90,0,1,0);

					//glRotatef(-90,1,0,0);
					GLUquadricObj *qObj = gluNewQuadric();
					gluQuadricNormals(qObj, GLU_SMOOTH);
					gluQuadricTexture(qObj, GL_TRUE);
					glEnable(GL_TEXTURE_2D);
					glBindTexture(GL_TEXTURE_2D, texture[BRIDGE_BRICK]); // texID is the texture ID of a

					gluQuadricOrientation(qObj, GLU_INSIDE);
					GLdouble eqn1[] = { 0, coOff_y, coOff_z, -1.0 };
					//glRotatef(180,0,0,1);
					glClipPlane(GL_CLIP_PLANE0, eqn1);
					glTranslatef(0, 0, offset);
					glEnable (GL_CLIP_PLANE0);
					gluCylinder(qObj, radofcylinder / 2, radofcylinder / 2, len,
							20, 20);
					glDisable(GL_CLIP_PLANE0);
				};
				glPopMatrix();
			}
		};
		glPopMatrix();
		//centraldisk
		CastleCenterDisk(1);
		CastleCenterDisk(-1);
		glPushMatrix();
		{
			float width = 17.56f;
			float height = 9.47f;
			glRotatef(-90, 1, 0, 0);
			glTranslatef(0, 18 - height / 2, 2.44);
			TexturedQuad(width, height, 0, 0, true, 1);
		}
		glPopMatrix();
		//middle ceiling
		glBindTexture(GL_TEXTURE_2D, texture[BRIDGE_BRICK]);
		glPushMatrix();
		{
			float width = 8.88f;
			float height = 18.66f;
			glTranslatef(0, 23.3 + 2.2 + 1.21, 0);
			glRotatef(-90, 1, 0, 0);
			TexturedQuad(width, height, 0, 0, true, 1);
		}
		glPopMatrix();
		glPushMatrix();
		{
			float width = 14.0f;
			float height = 18.66;
			glTranslatef(0, 23.3 + 2.2, 0);
			glRotatef(-90, 1, 0, 0);
			TexturedQuad(width, height, 0, 0, true, 1);
		}
		glPopMatrix();
		// transparent rellings
		glPushMatrix();
		{
			glDepthMask (GL_FALSE);
			glEnable (GL_BLEND);
			glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
			// now draw transparent objects
			float offSet = 18 - 0.6;
			CastleTopRelling(offSet);
			glPushMatrix();
			{
				glRotatef(180, 0, 1, 0);
				CastleTopRelling(offSet);
			}
			glPopMatrix();
			//middle part
			glBindTexture(GL_TEXTURE_2D, texture[BRIDGE_RELLING]);
			glPushMatrix();
			{
				float height = 4.0f;
				float width = 18.66f;
				glTranslatef(-4.44, 25.25 + height / 2, 0);
				glRotatef(-90, 0, 1, 0);
				//glRotatef(-90, 1, 0, 0);
				TexturedQuad(width, height, 0, 0, true, 1);
			}
			glPopMatrix();
			glBindTexture(GL_TEXTURE_2D, texture[BRIDGE_RELLING]);
			glPushMatrix();
			{
				float height = 4.0f;
				float width = 18.66f;
				glTranslatef(4.44, 25.25 + height / 2, 0);
				glRotatef(90, 0, 1, 0);
				//glRotatef(-90, 1, 0, 0);
				TexturedQuad(width, height, 0, 0, true, 1);
			}
			glPopMatrix();
			//side rellings
			glBindTexture(GL_TEXTURE_2D, texture[BRIDGE_RELLING]);
			glPushMatrix();
			{
				float height = 4.0f;
				float width = 7;
				glTranslatef(0, 2.44 + height / 2, -18);
				//glRotatef(-90,0,1,0);
				//glRotatef(-90, 1, 0, 0);
				TexturedQuad(width, height, 0, 0, true, 1);
			}
			glPopMatrix();
			glBindTexture(GL_TEXTURE_2D, texture[BRIDGE_RELLING]);
			glPushMatrix();
			{
				float height = 4.0f;
				float width = 7;
				glTranslatef(0, 2.44 + height / 2, 18);
				//glRotatef(-90,0,1,0);
				//glRotatef(-90, 1, 0, 0);
				TexturedQuad(width, height, 0, 0, true, 1);
			}
			glPopMatrix();
			glDisable(GL_BLEND);
			glDepthMask (GL_TRUE);
		};
		glPopMatrix();
	}
	glPopAttrib();
}

void HellGate::DrawPillar() {
	//pillar
	glPushAttrib (GL_ALL_ATTRIB_BITS);
	{
		glEnable (GL_COLOR_MATERIAL);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
		glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
		glBindTexture(GL_TEXTURE_2D, texture[BRIDGE_PILLAR_TOP]);
		float width1 = 7.2;
		float width2 = 20;
		glPushMatrix();
		{
			float height = 2.48;
			glTranslatef(0, -height / 2, 0);
			TopSweep(height, 0, 0, width1, width2, false);
		}
		glPopMatrix();
		//top
		glBindTexture(GL_TEXTURE_2D, texture[BRIDGE_PILLAR_MAIN]);
		glPushMatrix();
		{
			float height = 2.48;
			//glTranslatef(0, -height/2, 0);
			glRotatef(90, 1, 0, 0);
			TexturedQuad(width1, width2, 0, 0, false);
		}
		glPopMatrix();
		//leg
		float width = 4;
		float height = 36;
		width1 = 6;
		width2 = 5;
		glPushMatrix();
		{
			float height = 2.48;
			glTranslatef(0, -height / 2, 0);
			TopSweep(height, 0, 0, width1, width2, false);
		}
		glPopMatrix();
		glPushMatrix();
		{
			float height = 36;
			glTranslatef(0, -height / 2, 9);
			float shear[] =
					{ 1, 0, 0, 0, 0, 1, -0.1, 0, 0, 0, 1, 0, 0, 0, 0, 1 };
			glMultMatrixf(shear);
			TopSweep(height, 0, 2, width1, width2, false);
		}
		glPopMatrix();
		glPushMatrix();
		{
			float height = 36;
			glRotatef(180, 0, 1, 0);
			glTranslatef(0, -height / 2, 9);
			float shear[] =
					{ 1, 0, 0, 0, 0, 1, -0.1, 0, 0, 0, 1, 0, 0, 0, 0, 1 };
			glMultMatrixf(shear);
			TopSweep(height, 0, 2, width1, width2, false);
		}
		glPopMatrix();
		//circular
		//disk
		glPushMatrix();
		{
			double d = 10;
			glTranslatef(width1 / 2, -d, 0);
			glRotatef(90, 0, 1, 0);
			GLUquadricObj* qObj = gluNewQuadric();
			gluQuadricNormals(qObj, GLU_SMOOTH);
			gluQuadricTexture(qObj, GL_TRUE);
			glEnable(GL_TEXTURE_2D);
			glBindTexture(GL_TEXTURE_2D, texture[BRIDGE_PILLAR_MAIN]);
			gluQuadricOrientation(qObj, GLU_OUTSIDE);
			GLdouble eqn1[] = { 0.0, 1.0, 0.0, 0.0 };
			glClipPlane(GL_CLIP_PLANE0, eqn1);
			glEnable (GL_CLIP_PLANE0);
			gluDisk(qObj, d / 2, d / 2 + 5, 20, 20);
			glDisable(GL_CLIP_PLANE0);
		}
		glPopMatrix();
		glPushMatrix();
		{
			double d = 10;
			glTranslatef(-width1 / 2, -d, 0);
			glRotatef(90, 0, 1, 0);
			GLUquadricObj* qObj = gluNewQuadric();
			gluQuadricNormals(qObj, GLU_SMOOTH);
			gluQuadricTexture(qObj, GL_TRUE);
			glEnable(GL_TEXTURE_2D);
			glBindTexture(GL_TEXTURE_2D, texture[BRIDGE_PILLAR_MAIN]);
			gluQuadricOrientation(qObj, GLU_OUTSIDE);
			GLdouble eqn1[] = { 0.0, 1.0, 0.0, 0.0 };
			glClipPlane(GL_CLIP_PLANE0, eqn1);
			glEnable (GL_CLIP_PLANE0);
			gluDisk(qObj, d / 2, d / 2 + 5, 20, 20);
			glDisable(GL_CLIP_PLANE0);
		}
		glPopMatrix();
		glPushMatrix();
		{
			float rad = 10;
			float len = 6;
			glTranslatef(-len / 2, -rad, 0);
			glRotatef(90, 0, 1, 0);
			//glRotatef(-90,1,0,0);
			GLUquadricObj* qObj = gluNewQuadric();
			gluQuadricNormals(qObj, GLU_SMOOTH);
			gluQuadricTexture(qObj, GL_TRUE);
			glEnable(GL_TEXTURE_2D);
			glBindTexture(GL_TEXTURE_2D, texture[BRIDGE_PILLAR_MAIN]);
			glRotatef(180, 0, 0, 1);
			gluQuadricOrientation(qObj, GLU_INSIDE);
			GLdouble eqn0[] = { 0.0, -1.0, 0.0, 0.0 };
			glClipPlane(GL_CLIP_PLANE0, eqn0);
			glEnable (GL_CLIP_PLANE0);
			gluCylinder(qObj, rad / 2, rad / 2, len, 10, 10);
			glDisable(GL_CLIP_PLANE0);
		}
		glPopMatrix();
	}
	glPopAttrib();
}

void HellGate::DrawPillers() {
	//pillar
	for (int i = 0; i <= 3 * 50; i += 50) {
		glPushMatrix();
		{
			glTranslatef(-(240 + i), -7, 0);
			DrawPillar();
		}
		glPopMatrix();
		glPushMatrix();
		{
			glTranslatef((240 + i), -7, 0);
			DrawPillar();
		}
		glPopMatrix();
	}

}

void HellGate::DrawCastles() {
	//draw side castle
	glPushAttrib(GL_ALL_ATTRIB_BITS);{
		glDisable (GL_COLOR_MATERIAL);
		glColor4f(1, 1, 1, 1);
		glPushMatrix();
		{
			glTranslatef(160 + 18.0 / 2, -7, 0);
			DrawCastle();
		}
		glPopMatrix();
		glPushMatrix();
		{
			glTranslatef(-160 - 18.0 / 2, -7, 0);
			DrawCastle();
		}
		glPopMatrix();
	}glPopAttrib();
}

void HellGate::draw() {
	DrawMainBridge();
	glEnable(GL_TEXTURE_2D);
	//draw side castle
	DrawCastles();

	//pillar
	DrawPillers();



}

